package vn.edu.saigontech.ncms.model.teaching;

import java.util.Calendar;
import java.util.Date;

import javax.persistence.*;

import org.hibernate.annotations.OptimisticLockType;

import vn.edu.saigontech.ncms.model.BaseEntity;
import vn.edu.saigontech.ncms.model.enumeration.TeachingInterruptionReason;
import vn.edu.saigontech.ncms.model.info.Offering;
import vn.edu.saigontech.ncms.model.info.Teacher;
import vn.edu.saigontech.ncms.model.user.User;
import vn.edu.saigontech.ncms.util.Checker;
import vn.edu.saigontech.ncms.util.DateUtil;

@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true, optimisticLock = OptimisticLockType.ALL)
@Table(name = "ncms_teaching_interruption")
@SuppressWarnings("serial")
public class TeachingInterruption extends BaseEntity {
	public static int CANCEL_REASON = 2;
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "offering_id", nullable = false)
	private Offering offering;
	
	@ManyToOne
	@JoinColumn(name = "teacher_id")
	private Teacher teacher;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "from_date")
	private Date fromDate;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "to_date")
	private Date toDate;
	
	@Enumerated
	@Column(name = "reason")
	private TeachingInterruptionReason reason;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "makeup_from_date")
	private Date makeupFromDate;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "makeup_to_date")
	private Date makeupToDate;
	
	@ManyToOne
	@JoinColumn(name = "substitute_teacher_id")
	private Teacher substituteTeacher;
	
	@ManyToOne
	@JoinColumn(name = "staff_id")
	private User staff;
	
	@Column(name = "comment", length = 4000)
	private String comment;

	public boolean isForeverSubstitute() {
		return TeachingInterruptionReason.SUBSTITUTE.equals(this.reason) &&
			   this.toDate.equals(this.offering.getEndDate());
	}
	
	public boolean contains(Date date) {
		return DateUtil.isBetween(date, this.fromDate, this.toDate);
	}
	
	public boolean containMakeUps(Date date) {
		if(TeachingInterruptionReason.CANCEL.equals(this.getReason())) {
			if(Checker.isNotNull(this.makeupFromDate) && Checker.isNotNull(this.makeupToDate)) {
				return DateUtil.isBetween(date, this.makeupFromDate, makeupToDate);
			}
		}
		return false;
	}

	public int getStatus(Date date) {
		if (TeachingInterruptionReason.SUBSTITUTE.equals(this.getReason())) {
			if (DateUtil.isBetween(date, this.fromDate, DateUtil
					.getDateOfThisWeek(this.fromDate, Calendar.SATURDAY))) {
				return 1;
			} else {
				return 11;
			}
		} else if (TeachingInterruptionReason.CANCEL.equals(this.getReason())) {
			return 2;
		} 
		return 0;
	}

	public Offering getOffering() {
		return offering;
	}

	public void setOffering(Offering offering) {
		this.offering = offering;
	}

	public Teacher getTeacher() {
		return teacher;
	}

	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}

	public Date getFromDate() {
		return fromDate;
	}

	public void setFromDate(Date fromDate) {
		this.fromDate = fromDate;
	}

	public Date getToDate() {
		return toDate;
	}

	public void setToDate(Date toDate) {
		this.toDate = toDate;
	}

	public TeachingInterruptionReason getReason() {
		return reason;
	}

	public void setReason(TeachingInterruptionReason reason) {
		this.reason = reason;
	}

	public Teacher getSubstituteTeacher() {
		return substituteTeacher;
	}

	public void setSubstituteTeacher(Teacher substituteTeacher) {
		this.substituteTeacher = substituteTeacher;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public User getStaff() {
		return staff;
	}

	public void setStaff(User staff) {
		this.staff = staff;
	}

	public Date getMakeupFromDate() {
		return makeupFromDate;
	}

	public void setMakeupFromDate(Date makeupFromDate) {
		this.makeupFromDate = makeupFromDate;
	}

	public Date getMakeupToDate() {
		return makeupToDate;
	}

	public void setMakeupToDate(Date makeupToDate) {
		this.makeupToDate = makeupToDate;
	}
}